The Printing Message Overrides
The code that makes up your printing extension is a set of functions that override, either partially or totally, some of the printing messages that QuickDraw GX sends during the process of printing a document. The contents of the filebackwash.c
, which contains
the source code for the message overrides in the background picture printing extension, are shown in the QuickDraw GX sample code.QuickDraw GX provides a default implementation of each printing message that it sends. You can augment (partially override) some printing messages, and you can replace (totally override) others. For each printing message, QuickDraw GX provides one of three kinds of default implementations, as shown in Table 2-3.
Whenever you override a QuickDraw GX printing message, you must be certain that
the declaration of your override function matches the declaration of the message. This means that the type of function return and the type of each parameter must match the types in the message declaration. The chapter "Printing Messages" shows the declaration of each printing messages.When you partially override a printing message, you add some functionality to that provided by other message handlers, including QuickDraw GX (through its default implementation), the printer driver, and other printing extensions. You forward the message to these other handlers, as described in the section "Forwarding Messages"
on page 2-13.When you totally override a message, you replace any functionality that is provided
by other message handlers, including the default implementation. Your total message override does not forward the message to the other handlers. This means that you must be sure to replace the functionality that is provided by the default implementation.Although the default implementation of a message might be empty, other printing message handlers (the printer driver and other printing extensions) can also override messages, so you need to carefully consider whether or not to create a total override
of a message.Whether or not you can totally override a message and when you need to forward a message in your implementation of a partial override is specific to each message. The reference section "Printing Messages Reference" beginning on page 4-9 in the chapter "Printing Messages" provides this information for each message.
Choosing the Messages to Override
Which messages you need to override for your printing extension depends entirely on what you want your extension to do. There are not any messages that you are required to override. Some extensions override many messages to provide their operations, and many extensions are created by overriding only a few messages. Refer to the chapter "Printing Messages" in this book for complete information about the available messages.Forwarding Messages
Your printing extension can forward a message in its implementation of a partial override. If you are totally overriding a message, you do not forward it to other message handlers. You can forward the message either before or after performing your own actions. To forward a message to the next message handler in the message chain, use
a statement with the following format:
anErr = Forward_MessageName(arguments);For example, the background picture printing extension overrides theGXJobPrintDialog
message to add a panel to the Print dialog box. This message must be forwarded so that the default implementation can build the default dialog box and any other message handlers can add their panels to the dialog box. Listing 2-3 shows the override of theGXJobPrintDialog
message from the background picture extension.Listing 2-3 Forwarding the
GXJobPrintDialog
message
OSErr BWJobPrintDialog (gxDialogResult *dlogResult) { OSErr err; err = SetupPrintPanel(); if (!err) err = Forward_GXJobPrintDialog(dlogResult); return err; }This override function calls a local function namedSetupPrintPanel
to add items to the Print dialog box that are used for controlling the background picture extension. If that function succeeds, this version forwards the message to the next message handler, which can add its own panel. TheGXJobPrintDialog
message is described on page 4-84 in the chapter "Printing Messages."Sending Messages
Your printing extension can also send a printing message to other handlers in the message chain. When you send a message, QuickDraw GX receives it and then sends it to the first message handler in the chain. To send a message, use a statement with this format:
anErr = Send_GXMessageName(arguments);For example, to send theGXBufferData
message, which is described on page 4-139
in the chapter "Printing Messages," use the following statement:
anErr = Send_GXBufferData(gxDialogResult *);For more information on sending messages, refer to the chapter "Message Manager"
in Inside Macintosh: QuickDraw GX Environment and Utilities.Handling Exceptions in Your Message Overrides
The code samples presented in this chapter make use of an exception-handling strategy that simplifies the job of testing for error conditions after each function call. This strategy uses three C macros, each of which branches to an error-handling statement in response to a condition.The first macro,
nrequire
, branches to a label when the value of itscondition
argument is anything other than 0. This macro is commonly used to test the result code from a function call and branch if the function returned an error (any value other thannoErr
, which is 0). The syntax of thenrequire
macro is
nrequire(condition, location);An example of using thenrequire
macro is shown in Listing 2-4.Listing 2-4 Using the
nrequire
macro for exception handling
OSErr err; long count; short pictRefNum; PicHandle backwashPict = nil; err = FSpOpenDF(opFSSpec, fsCurPerm, &pictRefNum); nrequire(err, CouldNotOpenFile); err = GetEOF(pictRefNum, &count); nrequire(err, CouldNotGetEOF); count -= 512; err = SetFPos(pictRefNum, fsFromStart, 512); nrequire(err, CouldNotSetFilePos); ... CouldNotGetEof: CouldNotSetFilePos: FSClose(pictRefNum); CouldNotOpenFile: return(backwashPict); }The function in Listing 2-4 uses thenrequire
macro instead of using anif
statement
to test the value oferr
after each call. Thenrequire
macro performs a branch to the specified label if the value oferr
is anything other thannoErr
. Each label that is referenced by thenrequire
macro leads to a call that cleans up after the error.A variation of the
nrequire
macro that is used in some functions is therequire
macro. This macro is exactly the same asnrequire
except that it branches when itscondition
argument is 0 (whereasnrequire
branches on anything other than 0).
The syntax of therequire
macro is
require(condition, location);A final variation of thenrequire
macro that is used in some of the functions of the background picture printing extension is thenrequire_action
macro. This macro works the same way asnrequire
and additionally performs an action before branching. The syntax of thenrequire_action
macro is
nrequire_action(condition, location, action);The action is performed only if the value of thecondition
argument is anything other than 0. The action is performed before branching to the specified label. An example of thenrequire_action
macro is shown in Listing 2-5.Listing 2-5 Using the
nrequire_action
macro for exception handling
grErr = GetJobCollectionItem(&backwashConfig, nil, kBackwashCollectionType, kBackwashSettingsID); nrequire_action((!grErr && !backwashConfig.addBackwash && backwashConfig.haveFileInfo), NotAddingBackwash, grErr = noErr);Thenrequire_action
call in this example assigns the valuenoErr
to thegrErr
variable before branching to theNotAddingBackwash
label.
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help